/*
 * Crea una nueva lista simple enlazada.
 */
package estructuras;

/**
 * @author Alexandre
 * @author Rodrigo
 * @author Gabriel
 * @author Jeremy
 */

public class SLL {
    
    private SLLNode _head;//Nodo cabeza de la lista.
    private SLLNode _tail;//Nodo de la cola de la lista.
    private int _length;//Largo total de la lista.
    
    /**
     * Constructor, crea una nueva lista simple enlazada, inicializa
     * el nodo cabeza y el cola como nulos y su longitud en 0.
     */
    public SLL(){
        _head = null;
        _tail = null;
        _length = 0; 
    }
    
    /**
     * Obtiene el nodo cabeza de la lista.
     * @return El nodo que se encuentra a la cabeza de la lista
     */
    public SLLNode getHead () {
        return _head;
    }

    /**
     * Obtiene la longitud de la lista.
     * @return El tamaño de la lista
     */
    public int getLength () {
        return _length;
    }

    /**
     * Modifica el tamaño de la lista.
     * @param pLength El tamaño a establecer de la ista
     */
    public void setLength (int pLength) {
        this._length = pLength;
    }
    
    
    /**
     * Concatena la segunda lista al final de la primera.
     * @param pHeadLista1 Lista principal
     * @param pHeadLista2 Lista a concatenar
     * @return la lista final con las dos unidas
     */
    public static SLL unirListasSimples (SLLNode pHeadLista1, SLLNode pHeadLista2) {
        SLL aux = new SLL();
        
        for(SLLNode temp = pHeadLista1 ;temp != null;temp = temp.getNext()){
            aux.meterFinal(temp.getElemento());
        }
        for(SLLNode temp = pHeadLista2;temp != null;temp = temp.getNext()){
            aux.meterFinal(temp.getElemento());
        }
        aux.imprimir();
        
        return aux;        
    }
    
    /**
     * Crea un nuevo nodo con enlace a nulo
     * @param pPorCrear Objeto para insertar como elemento al nuevo nodo
     * @return El nodo creado
     */
    public SLLNode crearNodo (Object pPorCrear){
        SLLNode temp = new SLLNode(pPorCrear);
        return temp;
    }
    
    /**
     * Inserta el nodo primero de la lista
     * @param pTmp nodo a insertar
     */
    public void meterHead (SLLNode pTmp){       
        _head = _tail = pTmp;
        _length++;
    }
    
    /**
     * Inserta el nodo a la cola de la lista
     * @param pPorMeter Elemento para el nodo final
     */
    public void meterFinal (Object pPorMeter){
        SLLNode temp = crearNodo(pPorMeter);
        if (_length == 0){
            meterHead(temp);
        }
        else{
            _tail.setNext(temp); 
            _tail = temp;                           
            _length++;         
        }   
    }
    
    public void meterFinal (SLLNode pPorMeter) {
        if (_length == 0){
            _head = pPorMeter;
        }
        else{
            _tail.setNext(pPorMeter); 
            _tail = pPorMeter;                           
            _length++;         
        }
    }
    
    /**
     * Obtiene el elemento de un nodo por su posicion en la lista.
     * @param pCasillaPorObtener Posicion de la lista para buscar
     * @return El elemento del nodo
     */
    public Object obtenerPorPosicion (int pCasillaPorObtener){
       
        if (pCasillaPorObtener == 1){            
            return _head.getElemento();            
        }        
        else{            
            int contador = 2;
            SLLNode temp = _head.getNext();
            while(contador  != pCasillaPorObtener){
                temp = temp.getNext();
                contador++;
            }
            return temp.getElemento();
        }
        
        
    }
    
    /**
     * Elimina un nodo de acuerdo a su posicion en la lista.
     * @param pCasillaPorEliminar Posicion en la lista donde se encuentra el nodo por eliminar
     */
    public void eliminaPorPosicion (int pCasillaPorEliminar){
        if (pCasillaPorEliminar == 1){
            _head = _head.getNext();  
            _length--;          
        }
        else{
            int contador = 1;
            SLLNode temp = _head;
            while(contador +1 != pCasillaPorEliminar){
                temp = temp.getNext();
                contador++;
            }
            temp.setNext(temp.getNext());
            _length--;
        }
        
        
    }
    
    /**
     * Buscar un elemento en la lista y dar su posicion en ella.
     * @param pPorBuscar Elemento a buscar
     * @return La posicion en la lista del elemento encontrado, cero si no lo encuentra
     */
    public int buscarYDarPosicion (Object pPorBuscar){
        int posicion = 1;
        for (SLLNode temp = _head; temp != null; temp = temp.getNext()){
            if (temp.getElemento() == pPorBuscar){
                System.out.println("true, esta en la posicion es: " +posicion);
                return posicion;
            }
            posicion++;
        }
        System.out.println("false, no se encontró el elemento");
        return 0;
    }
    
    /**
     * Imprime el contenido de la lista
     */
    public void imprimir (){
        SLLNode aux=_head;
        while (aux!=null){
          System.out.print(aux.getElemento() + ", ");  
          aux=aux.getNext();
        }
//        for (SLLNode aux = _head; aux != null; aux = aux.getNext()) {
//            System.out.println("entra");
//            System.out.println(aux.getElemento() +"pru");
//            System.out.print(aux.getElemento() + ", ");
//        }
        System.out.println("");
        System.out.println("tamaño_lista = "+_length);
    }
    
//    public static void main(String[] args) {  
//        SLL listaSimple1 = new SLL();
//        SLL listaSimple2 = new SLL(); 
//        
//        listaSimple1.meterFinal(1);
//        listaSimple1.meterFinal(2);
//        listaSimple1.meterFinal(3);
//        listaSimple1.meterFinal(4);
//        listaSimple1.meterFinal(5);
//        listaSimple1.meterFinal(6);
//        listaSimple1.meterFinal(7);
//        listaSimple1.meterFinal(8);
//        listaSimple1.meterFinal(9);
//        System.out.println("lista 1");
//        listaSimple1.imprimir();
//        
//        listaSimple2.meterFinal(11);
//        listaSimple2.meterFinal(12);
//        listaSimple2.meterFinal(13);
//        listaSimple2.meterFinal(14);
//        listaSimple2.meterFinal(15);
//        listaSimple2.meterFinal(16);
//        listaSimple2.meterFinal(17);
//        listaSimple2.meterFinal(18);
//        listaSimple2.meterFinal(19);
//        System.out.println("lista 2");
//        listaSimple2.imprimir();
//        
//        
//        listaSimple.imprimir();
//        
//        listaSimple.buscarYDarPosicion(5);
//        
//        listaSimple.imprimir();
//         
//        SLL listaSimple3 ;
//        listaSimple3 = unirListasSimples(listaSimple2._head,listaSimple1._head);
//         
//         listaSimple3.ordenar();
//    }
//    
}
